﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Collections.ObjectModel;
using System.ComponentModel;

using System.Windows.Input;

using System.Windows.Controls;

using System.Windows;


using System.Windows.Media;

namespace HA.ModFlow.Application
{

    /// <summary>
    /// 用于treeviewitem
    /// </summary>
    public class MDTVIViewModel : INotifyPropertyChanged
    {

        #region 构造函数

        public MDTVIViewModel()
        {
            _children = new ObservableCollection<MDTVIViewModel>();


         

 
        }

        protected MDTVIViewModel(MDTVIViewModel parent, bool lazyLoadChildren)
        {
            _parent = parent;

            _children = new ObservableCollection<MDTVIViewModel>();

            if (lazyLoadChildren)
                _children.Add(DummyChild);




         

           

        }

        #endregion


        #region Data


        static readonly MDTVIViewModel DummyChild = new MDTVIViewModel();

        bool _isExpanded=true;
        bool _isSelected;

        bool _isChecked = true;

        readonly ObservableCollection<MDTVIViewModel> _children;
        readonly MDTVIViewModel _parent;


        protected VMImageSource _imageSource;


        protected bool _isShowCheck = true;

   

    

        #endregion

        #region commands

        public virtual ICommand DoubleClickCommand
        {
            get {

                //return ModflowV2Commands.EditHK;

                return null;

            
            }
        }

        #endregion


        #region Presentation Members



        public bool IsShowCheck
        {
            get { return _isShowCheck; }
            set { _isShowCheck = value; }
        }


        #region imageSource



        public VMImageSource ImageSource
        {
            get { return _imageSource; }

        }

        #endregion

        #region 右键菜单

        protected ContextMenu _contextMenu;

        public ContextMenu ContextMenu
        {
            get { return _contextMenu; }
            set { _contextMenu = value;

            this.OnPropertyChanged("ContextMenu");

            }
        }

     
      

        #endregion


        #region 对外描述

        public virtual string Desc
        {
            get { return ""; }
        }

        #endregion

        #region Children

        /// <summary>
        /// Returns the logical child items of this object.
        /// </summary>
        public ObservableCollection<MDTVIViewModel> Children
        {
            get { return _children; }
        }

        #endregion // Children

        #region HasLoadedChildren

        /// <summary>
        /// Returns true if this object's Children have not yet been populated.
        /// </summary>
        public bool HasDummyChild
        {
            get { return this.Children.Count == 1 && this.Children[0] == DummyChild; }
        }

        #endregion // HasLoadedChildren

        #region IsChecked

        /// <summary>
        /// Gets/sets the state of the associated UI toggle (ex. CheckBox).
        /// The return value is calculated based on the check state of all
        /// child FooViewModels.  Setting this property to true or false
        /// will set all children to the same check state, and setting it 
        /// to any value will cause the parent to verify its check state.
        /// </summary>
        public bool IsChecked
        {
            get { return _isChecked; }
            set { this.SetIsChecked(value, true, true); }
        }

        void SetIsChecked(bool value, bool updateChildren, bool updateParent)
        {
            if (value == _isChecked)
                return;

            _isChecked = value;

            if (updateChildren)
            {
                foreach (MDTVIViewModel  item in this._children)
                {
                    item.SetIsChecked(value,true,false);
                    
                }
            }

            if (updateParent && _parent != null)
                _parent.VerifyCheckState();


            //付加 ，内部处理

            this.OnCheckedChanged();

            this.OnPropertyChanged("IsChecked");
        }


        protected virtual void OnCheckedChanged()
        { 

        }

        void VerifyCheckState()
        {
            bool state=false;
            for (int i = 0; i < this._children.Count; ++i)
            {
                bool current = this._children[i].IsChecked;
                if (i == 0)
                {
                    state = current;
                }
                else if (state != current)
                {
                  //  state = null;
                    break;
                }
            }
            this.SetIsChecked(state, false, true);
        }

        #endregion // IsChecked

        #region IsExpanded

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is expanded.
        /// </summary>
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    this.OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root.
                if (_isExpanded && _parent != null)
                    _parent.IsExpanded = true;

                // Lazy load the child items, if necessary.
                if (this.HasDummyChild)
                {
                    this.Children.Remove(DummyChild);
                    this.LoadChildren();
                }
            }
        }

        #endregion // IsExpanded

        #region IsSelected

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is selected.
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    this.OnSelectedChanged();
                    this.OnPropertyChanged("IsSelected");
                }
            }
        }

        protected virtual void OnSelectedChanged()
        { 

        }

        #endregion // IsSelected

        #region LoadChildren

        /// <summary>
        /// Invoked when the child items need to be loaded on demand.
        /// Subclasses can override this to populate the Children collection.
        /// </summary>
        protected virtual void LoadChildren()
        {
        }

        #endregion // LoadChildren

        #region Parent

        public MDTVIViewModel Parent
        {
            get { return _parent; }
        }

        #endregion // Parent


        #endregion

        #region INotifyPropertyChanged Members

        protected void OnPropertyChanged(string prop)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion


    }


    public class RelayCommand : ICommand
    {
        private Action<object> _Execute;
        private Predicate<object> _CanExecute;

        public RelayCommand(Action<object> execte)
            : this(execte, null)
        {
        }
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("Execute");
            _Execute = execute;
            _CanExecute = canExecute;
        }
        public bool CanExecute(object parameter)
        {
            return _CanExecute == null ? true : _CanExecute(parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { System.Windows.Input.CommandManager .RequerySuggested += value; }
            remove { System.Windows.Input.CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            _Execute(parameter);
        }
    }


    public class MDCTest
    {
        public static DependencyProperty MouseDoubleClickCommandProperty = DependencyProperty.RegisterAttached(
            "MouseDoubleClick",
            typeof(ICommand),
            typeof(MDCTest),
            new FrameworkPropertyMetadata(null, new PropertyChangedCallback(MouseDoubleClickChanged))
            );
        public static void SetMouseDoubleClick(DependencyObject target, ICommand value)
        {
            target.SetValue(MDCTest.MouseDoubleClickCommandProperty, value);
        }
        public static ICommand GetMouseDoubleClick(DependencyObject target)
        {
            return (ICommand)target.GetValue(MDCTest.MouseDoubleClickCommandProperty);
        }
        private static void MouseDoubleClickChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            Control control = target as Control;


            //TreeViewItem control = target as TreeViewItem;

            if (control != null)
            {
                if (e.NewValue != null && e.OldValue == null)
                {
                    control.MouseDoubleClick += new MouseButtonEventHandler(control_MouseDoubleClick);
                }
                else if (e.NewValue == null && e.OldValue != null)
                {
                    control.MouseDoubleClick -= new MouseButtonEventHandler(control_MouseDoubleClick);
                }
            }
        }
        public static void control_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {


            //默认只从最原始处触发

            // Only react to the Selected event raised by the TreeViewItem
            // whose IsSelected property was modified.  Ignore all ancestors
            // who are merely reporting that a descendant's Selected fired.
            //if (!Object.ReferenceEquals(sender, e.OriginalSource))
            //    return;

            //if (e.or)
            //{
                
            //}



            DependencyObject child = e.OriginalSource as DependencyObject;

           







            while (child != null && !(child is TreeViewItem))
            {
                child = VisualTreeHelper.GetParent(child);
            }



            e.Handled = true;


            if (!object.ReferenceEquals(sender, child))
            {

                return;

            }


            //if (!Object.ReferenceEquals(sender, e.OriginalSource))
            //{

            //}

           


            Control control = sender as Control;
            ICommand command = (ICommand)control.GetValue(MDCTest.MouseDoubleClickCommandProperty);
            command.Execute(control);


         
        }
    }




}
